#
#    Copyright (C) 2016 Francisco Javier Parra <franparpe@openmailbox.org>
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
#

from PyQt5.QtWidgets import QFrame
from PyQt5.QtWidgets import QComboBox
from PyQt5.QtWidgets import QGridLayout
from PyQt5.QtWidgets import QLabel
from PyQt5.QtWidgets import QLineEdit

from PyQt5 import QtCore

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s


class ParamBoxForSections(QFrame):
    """This elements stores the input widgets
for the the movement law 

    """
    def __init__(self, parent, index=0, transaltionMov=True):
        super(ParamBoxForSections, self).__init__(parent)

        self.index = index
        self.previousType = _fromUtf8("Harmonic")
        # section Types
        self.doubleHamornic = _fromUtf8(_fromUtf8("DoubleHarmonic"))
        self.bezier = _fromUtf8(_fromUtf8("Bezier"))
        self.transaltionMov = transaltionMov
        self.create_normal_box()

        # Connections
        self.sectionTypeList_CboBox.currentIndexChanged.connect(self.changeBox)
        self.sectionTypeList_CboBox.currentIndexChanged.connect(self.setLastLablesContent)

    def create_normal_box(self):
        """
        
        """
        # Aesthetics
        self.setFrameShape(self.StyledPanel)
        self.setFrameShadow(self.Raised)

        # Now the Grid
        self.grid = QGridLayout(self)

        # Now, initialize the labels
        self.initialAngle_Label = QLabel(self)
        self.endAngle_Label = QLabel(self)
        self.sectionTypeList_Label = QLabel(self)
        self.initialPosition_Label = QLabel(self)
        self.displacement_Label = QLabel(self)

        # Now to put the text in the labels
        self.initialAngle_Label.setText(_fromUtf8("Initial\nAngle [º]"))
        self.endAngle_Label.setText(_fromUtf8("End\nAngle [º]"))
        self.sectionTypeList_Label.setText(_fromUtf8("Type of motion"))

        # Time for the lineEdits and the combobox
        self.initialAngle_LEdit = QLineEdit(self)
        self.endAngle_LEdit = QLineEdit(self)
        self.sectionTypeList_CboBox = QComboBox(self)
        self.initialPosition_LEdit = QLineEdit(self)
        self.displacement_LEdit = QLineEdit(self)

        # the items
        self.sectionTypeList_CboBox.addItem(_fromUtf8("Harmonic"))
        self.sectionTypeList_CboBox.addItem(_fromUtf8("Cycloidal"))
        self.sectionTypeList_CboBox.addItem(_fromUtf8("5º degree polynomial"))
        self.sectionTypeList_CboBox.addItem(_fromUtf8("7º degree polynomial"))
        self.sectionTypeList_CboBox.addItem(_fromUtf8("Demiharmonic Vi=0"))
        self.sectionTypeList_CboBox.addItem(_fromUtf8("Demiharmonic Vf=0"))
        self.sectionTypeList_CboBox.addItem(_fromUtf8("Demicycloidal Vi=0"))
        self.sectionTypeList_CboBox.addItem(_fromUtf8("Demicycloidal Vf=0"))
        self.sectionTypeList_CboBox.addItem(self.doubleHamornic)
        self.sectionTypeList_CboBox.addItem(_fromUtf8("Modified sinusoidal"))
        self.sectionTypeList_CboBox.addItem(_fromUtf8("Trapezoidal"))
        self.sectionTypeList_CboBox.addItem(_fromUtf8("Dwell"))
        self.sectionTypeList_CboBox.addItem(self.bezier)

        # placing everything in the grid
        self.grid.addWidget(self.initialAngle_Label, 0, 0, 1, 1)
        self.grid.addWidget(self.endAngle_Label, 0, 1, 1, 1)
        self.grid.addWidget(self.sectionTypeList_Label, 0, 2, 1, 1)
        self.grid.addWidget(self.initialPosition_Label, 0, 3, 1, 1)
        self.grid.addWidget(self.displacement_Label, 0, 4, 1, 1)
        self.grid.addWidget(self.initialAngle_LEdit, 1, 0, 1, 1)
        self.grid.addWidget(self.endAngle_LEdit, 1, 1, 1, 1)
        self.grid.addWidget(self.sectionTypeList_CboBox, 1, 2, 1, 1)
        self.grid.addWidget(self.initialPosition_LEdit, 1, 3, 1, 1)
        self.grid.addWidget(self.displacement_LEdit, 1, 4, 1, 1)

        # Te last contents
        self.setLastLablesContent()
        
    def DeleteItsElements(self):
        self.sectionTypeList_Label.deleteLater()
        self.initialAngle_Label.deleteLater()
        self.endAngle_Label.deleteLater()
        self.initialPosition_Label.deleteLater()
        self.displacement_Label.deleteLater()

        self.sectionTypeList_CboBox.deleteLater()
        self.initialAngle_LEdit.deleteLater()
        self.endAngle_LEdit.deleteLater()
        self.initialPosition_LEdit.deleteLater()
        self.displacement_LEdit.deleteLater()

        self.grid.deleteLater()

        self.deleteLater()

    def setTranslationMovement(self, translatingMov):
        """nothing yet
        """
        self.transaltionMov = translatingMov

    def setLastLablesContent(self):
        if self.transaltionMov is True:
            units = _fromUtf8("[mm]")
        else:
            units = _fromUtf8("[º]")

        if self.getLawType() == self.bezier:
            if self.modeSelector.currentText() == "Maximum selection":
                initialPosText = _fromUtf8("Lowest position\n")
                displacementText = _fromUtf8("Maximum point\n")
            else:
                initialPosText = _fromUtf8("Position at the\nbeginning ")
                displacementText = _fromUtf8("Position at the\nend ")
        else:
            initialPosText = _fromUtf8("Initial\nposition ")
            displacementText = _fromUtf8("Displacement\n")

        initialPosText += units
        displacementText += units
        self.initialPosition_Label.setText(initialPosText)
        self.displacement_Label.setText(displacementText)

    def extendWithdoubleHarmonic(self):
        """Non editable edits has NE in its name
        """
        # Not editable line edits
        self.initialAngle_LEditNE = QLineEdit(self)
        self.endAngle_LEditNE = QLineEdit(self)
        self.initialPosition_LEditNE = QLineEdit(self)
        self.displacement_LEditNE = QLineEdit(self)

        # Make them not editable
        self.initialAngle_LEditNE.setReadOnly(True)
        self.endAngle_LEditNE.setReadOnly(True)
        self.initialPosition_LEditNE.setReadOnly(True)
        self.displacement_LEditNE.setReadOnly(True)

        # The label with the other half
        self.secType_LabelNE = QLabel(self)
        self.secType_LabelNE.setText(_fromUtf8("DoubleHarmonic"))

        # Placing everything
        self.grid.addWidget(self.initialAngle_LEditNE, 2, 0, 1, 1)
        self.grid.addWidget(self.endAngle_LEditNE, 2, 1, 1, 1)
        self.grid.addWidget(self.secType_LabelNE, 2, 2, 1, 1)
        self.grid.addWidget(self.initialPosition_LEditNE, 2, 3, 1, 1)
        self.grid.addWidget(self.displacement_LEditNE, 2, 4, 1, 1)

        # Initializing if necessary
        self._write_on_other_angles()
        self._write_diplacement_double_harm()
        self._write_initial_pos_double_harm()

        # Signals
        self.endAngle_LEdit.textChanged.connect(self._write_on_other_angles)
        self.initialPosition_LEdit.textChanged.connect(self._write_diplacement_double_harm)
        self.displacement_LEdit.textChanged.connect(self._write_initial_pos_double_harm)

    def extendWithBezier(self):
        # Combobox to select the mode
        self.modeSelector = QComboBox(self)
        self.modeSelector.addItem(_fromUtf8("Maximum selection"))
        self.modeSelector.addItem(_fromUtf8("First and last"))

        # Labels
        self.contVect_Label = QLabel(self)
        self.contVect_Label.setText(_fromUtf8("Coninuity:"))
        self.bezModeSelector_Label = QLabel(self)
        self.bezModeSelector_Label.setText(_fromUtf8("Mode:"))

        # LineEdit
        self.contVect_LEdit = QLineEdit(self)

        # Placing in the grid
        self.grid.addWidget(self.bezModeSelector_Label, 2, 1, 1, 1)
        self.grid.addWidget(self.modeSelector, 2, 2, 1, 1)
        self.grid.addWidget(self.contVect_Label, 2, 3, 1, 1)
        self.grid.addWidget(self.contVect_LEdit, 2, 4, 1, 1)

        # Connections
        self.modeSelector.currentIndexChanged.connect(self.setLastLablesContent)

    def _destroyDoubleHarmonicExtension(self):
        """It destroys the double harmonic extension
        """
        self.initialAngle_LEditNE.deleteLater()
        self.endAngle_LEditNE.deleteLater()
        self.initialPosition_LEditNE.deleteLater()
        self.displacement_LEditNE.deleteLater()
        self.secType_LabelNE.deleteLater()

        self.endAngle_LEdit.textChanged.disconnect()
        self.initialPosition_LEdit.textChanged.disconnect()
        self.displacement_LEdit.textChanged.disconnect()

    def _destroyBezierExtension(self):
        """It destroy the bezier's extra witdgets
        """
        self.modeSelector.currentIndexChanged.disconnect()
        self.bezModeSelector_Label.deleteLater()
        self.modeSelector.deleteLater()
        self.contVect_Label.deleteLater()
        self.contVect_LEdit.deleteLater()
        
    def _write_on_other_angles(self):
        endAngleTxt = self.endAngle_LEdit.text()
        iniAngleTxt = self.initialAngle_LEdit.text()
        try:
            doubleEndAngle = str((float(endAngleTxt) - float(iniAngleTxt)) * 2)
        except:
            doubleEndAngle = "0"

        self.initialAngle_LEditNE.setText(endAngleTxt)
        self.endAngle_LEditNE.setText(doubleEndAngle)

    def _write_diplacement_double_harm(self):
        try:
            displ = str(-float(self.displacement_LEdit.text()))
        except:
            displ = "Non valid"
        self.displacement_LEditNE.setText(displ)

    def _write_initial_pos_double_harm(self):
        displ = self.displacement_LEdit.text()
        initPos = self.initialPosition_LEdit.text()
        try:
            newInitPos = str(float(displ) + float(initPos))
        except:
            newInitPos = "Non valid"
        self.initialPosition_LEditNE.setText(newInitPos)

    def getInitialAngle(self):
        """Returns the initial angle
        """
        return float(self.initialAngle_LEdit.text())

    def getEndAngle(self):
        """Returns the end angle of the section
        """
        return float(self.endAngle_LEdit.text())

    def getLawType(self):
        """Returns the current law selected
        """
        return self.sectionTypeList_CboBox.currentText()

    def getInitialPosition(self):
        """Returns the initial position
        """
        return float(self.initialPosition_LEdit.text())

    def getDisplacement(self):
        """Returns the value of the displacement
        
        """
        return float(self.displacement_LEdit.text())

    def getBezierContinuity(self):
        try:
            return int(self.contVect_LEdit.text())
        except:
            print("Use and integer")

    def getBezierMode(self):
        try:
            return self.modeSelector.currentText()
        except:
            print("The mode selector does not exists")

    def changeBox(self):
        if (self.previousType == self.doubleHamornic):
            self._destroyDoubleHarmonicExtension()
        elif (self.previousType == self.bezier):
            self._destroyBezierExtension()
        else:
            pass

        if self.getLawType() == self.doubleHamornic:
            self.extendWithdoubleHarmonic()
        elif self.getLawType() == self.bezier:
            self.extendWithBezier()
        else:
            pass

        self.previousType = self.getLawType()
